﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace efuture.http
{
    public class HttpHelper
    {
        public const String TOKEN_KEY = "token";

        /// <summary>
        ///     token 
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public static String Token
        {
            get;
            set;
        }

        public static String UserId
        {
            get;
            set;
        }

        public static String UserCode
        {
            get;
            set;
        }

        private static String _ServerURL = "";
        public static String ServerURL
        {
            get
            {
                return _ServerURL;
            }
            set
            {
                if (value.EndsWith("/"))
                {
                    _ServerURL = value;
                }
                else
                {
                    _ServerURL = value + "/";
                }
            }
        }

        /// <summary>
        ///     8k buff
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        const int BUFF_SIZE = 8192;

        private static HttpWebRequest GetWebRequest(String url, String method, IDictionary<String, String> parameters)
        {
            url = BuildQuery(url, parameters);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.ServicePoint.Expect100Continue = false;
            request.Method = method;
            request.KeepAlive = true;
            request.UserAgent = "C#.HttpHelper";
            request.ContentType = "text/xml;charset=utf-8";
            request.Timeout = 60000;

            if (!String.IsNullOrEmpty(Token))
            {
                request.Headers.Add(TOKEN_KEY, Token);
            }

            return request;
        }
        /// <summary>
        ///     
        /// </summary>
        /// <param name="url" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="xmlData" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="parameters" type="System.Collections.Generic.IDictionary<string,string>">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <returns>
        ///     A string value...
        /// </returns>
        public static string DoPost(String url, String xmlData, IDictionary<string, string> parameters)
        {
            //using (WaitDialogForm wdf = new WaitDialogForm())
            {
                HttpWebRequest request = GetWebRequest(url, "POST", parameters);

                if (!String.IsNullOrEmpty(xmlData))
                {
                    byte[] postData = Encoding.UTF8.GetBytes(xmlData);
                    Stream reqStream = request.GetRequestStream();
                    reqStream.Write(postData, 0, postData.Length);
                    reqStream.Close();
                }

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                return GetResponseAsString(response, Encoding.GetEncoding(response.CharacterSet));
            }
        }

        public static string DoGet(String url, IDictionary<string, string> parameters)
        {
            //using (WaitDialogForm wdf = new WaitDialogForm())
            {
                HttpWebRequest request = GetWebRequest(url, "GET", parameters);

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                return GetResponseAsString(response, Encoding.GetEncoding(response.CharacterSet));
            }
        }

        private static string GetResponseAsString(HttpWebResponse response, Encoding encoding)
        {
            String _token = response.Headers.Get(TOKEN_KEY);
            if (!String.IsNullOrEmpty(_token))
            {
                Token = _token;
            }

            StringBuilder result = new StringBuilder();
            Stream stream = null;
            StreamReader reader = null;
            //MessageBox.Show(String.Format("{0} GetResponseAsString()", DateTime.Now.ToString("HH:mm:ss.fff")));
            try
            {
                // 以字符流的方式读取HTTP响应
                stream = response.GetResponseStream();
                reader = new StreamReader(stream, encoding);

                // 每次读取不大于BUFF_SIZE个字符，并写入字符串
                char[] buffer = new char[BUFF_SIZE];
                int readBytes = 0;
                while ((readBytes = reader.Read(buffer, 0, buffer.Length)) > 0)
                {
                    result.Append(buffer, 0, readBytes);
                }
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (response != null) response.Close();
            }
            //MessageBox.Show(String.Format("{0} GetResponseAsString()", DateTime.Now.ToString("HH:mm:ss.fff")));

            return result.ToString();
        }

        private static string BuildQuery(String url, IDictionary<string, string> parameters)
        {
            StringBuilder sb = new StringBuilder(ServerURL).Append(url.StartsWith("/") ? url.Substring(1) : url);

            bool hasMark = url.Contains('?');

            if (parameters != null)
            {
                foreach (KeyValuePair<String, String> kvp in parameters)
                {
                    if (!String.IsNullOrEmpty(kvp.Key) && !String.IsNullOrEmpty(kvp.Value))
                    {
                        if (hasMark)
                        {
                            sb.Append("&").Append(kvp.Key).Append("=").Append(Uri.EscapeDataString(kvp.Value));
                        }
                        else
                        {
                            sb.Append("?").Append(kvp.Key).Append("=").Append(Uri.EscapeDataString(kvp.Value));
                            hasMark = true;
                        }
                    }
                }
            }

            return sb.ToString();
        }
    }
}
